package com.markyao.service;

import com.markyao.service.redis.UtilsKeys;
import com.markyao.vo.pojo.AppBean;
import com.markyao.vo.pojo.ServiceBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j(topic = "m.RedisService")
@Service
public class RedisService extends AbstractViewService{
    @Autowired
    StringRedisTemplate redisTemplate;

    @Override
    protected void refreshAppbeansBuf(List<AppBean> appbeanBuffers) {
        Set<String> registryKeys = redisTemplate.keys(UtilsKeys.SERVER_REGISTRY_KEY+"*");
        log.info("发现已注册主机数量 =>  {}", registryKeys.size());
        for (String registryKey : registryKeys) {
            Map<Object, Object> entries = redisTemplate.opsForHash().entries(registryKey);
            String appName = entries.get(UtilsKeys.APPNAME).toString();
            String url = entries.get(UtilsKeys.URL).toString();
            String weight = entries.get(UtilsKeys.WEIGHT).toString();
            String alive=buildAlive(appName,url);
            AppBean appBean=new AppBean();
            appBean.setAppName(appName);
            appBean.setUrl(url);
            appBean.setWeight(weight);
            appBean.setAlive(alive);
            appbeanBuffers.add(appBean);
        }
    }

    @Override
    protected void refreshServicesBuffers(List<ServiceBean> servicesBuffers) {
        Set<String> providersKeys = redisTemplate.keys(UtilsKeys.PROVIDERS_KEY + "*");
        for (String providersKey : providersKeys) {
            String interfaceName = providersKey.substring(UtilsKeys.PROVIDERS_KEY.length());
            Map<Object, Object> entries = redisTemplate.opsForHash().entries(providersKey);
            for (Map.Entry<Object, Object> e : entries.entrySet()) {
                String url = e.getKey().toString();
                String appName = redisTemplate.opsForValue().get(UtilsKeys.URL_MAP_KEY + url).toString();
                ServiceBean serviceBean = new ServiceBean();
                serviceBean.setProviderName(appName);
                serviceBean.setInterfaceName(interfaceName);
                String instance = redisTemplate.opsForHash()
                        .get(UtilsKeys.SERVICE_REGISTRY_KEY + appName, interfaceName).toString();
                serviceBean.setInstanceName(instance);
                serviceBean.setDetails("...");
                servicesBuffers.add(serviceBean);
            }
        }
    }

    @Override
    protected String getHealth(String appName) {
        return null;
    }


    private Boolean isAlive(String appName, String url) {
        return redisTemplate.hasKey(UtilsKeys.buildHeartBeatKey(appName, url));
    }


    @Override
    protected Set<String> getConnectSetByAppName(String appName) {
        return redisTemplate.opsForSet().members(UtilsKeys.CONNECT_KEY + appName);
    }

    @Override
    protected Set<String> getConnectSetByKey() {
        return redisTemplate.keys(UtilsKeys.CONNECT_KEY + "*");
    }

    @Override
    protected Set<String> getConnectSetByKey(String key) {
        return redisTemplate.opsForSet().members(key);
    }

    @Override
    protected Boolean isConnecting(String appName) {
        return redisTemplate.hasKey(UtilsKeys.CONNECT_KEY + appName);
    }

    @Override
    protected Set<String> getRefrenceSetByAppName(String appName) {
        return redisTemplate.opsForSet().members(UtilsKeys.REFRENCE_REGISTRY_KEY + appName);
    }

    @Override
    protected Boolean isRefrence(String appName) {
        return redisTemplate.hasKey(UtilsKeys.REFRENCE_REGISTRY_KEY + appName);
    }

    @Override
    protected Map<Object, Object> getBeanMapFromServicesByAppName(String appName) {
        return redisTemplate.opsForHash().entries(UtilsKeys.SERVICE_REGISTRY_KEY + appName);
    }

    @Override
    protected Map<Object, Object> getBeanMapFromServersByAppName(String appName) {
        return redisTemplate.opsForHash().entries(UtilsKeys.SERVER_REGISTRY_KEY + appName);
    }

    @Override
    protected Boolean isProvider(String appName) {
        return redisTemplate.hasKey(UtilsKeys.SERVER_REGISTRY_KEY + appName);
    }



    /**
     * 通过服务名获取服务url
     * @param appName
     * @return
     */
    @Override
    protected String getUrl(String appName) {
        String key = UtilsKeys.SERVER_REGISTRY_KEY + appName;
        Object url = redisTemplate.opsForHash().get(key, UtilsKeys.URL);
        if (url!=null){
            return url.toString();
        }
        return null;
    }

    @Override
    protected Boolean isHeartBeat(String heartBeatKey) {
        return redisTemplate.hasKey(heartBeatKey);
    }


    @Override
    public void closeConnect(String curApp, String tarApp) {
        String key = UtilsKeys.KILL_CONNECT_KEY + curApp;
        redisTemplate.opsForSet().add(key,tarApp);
    }

    @Override
    public void reConnect(String curApp, String tarApp) {
        String key = UtilsKeys.RE_CONNECT_KEY + curApp;
        redisTemplate.opsForSet().add(key,tarApp);
    }


}
